home *** CD-ROM | disk | FTP | other *** search
/ Aminet 33 / Aminet 33 - October 1999.iso / Aminet / util / cli / WDelta.lha / WDelta / src / wdelta.asm < prev    next >
Encoding:
Assembly Source File  |  1999-07-07  |  20.4 KB  |  1,035 lines

  1. ;*---------------------------------------------------------------------------
  2. ;  :Program.    wdelta.asm
  3. ;  :Contents.    create wdelta file
  4. ;  :Author.    Bert Jahn
  5. ;  :EMail.    wepl@kagi.com
  6. ;  :Address.    Franz-Liszt-Straße 16, Rudolstadt, 07404, Germany
  7. ;  :Version.    $Id: wdelta.asm 1.1 1999/07/06 21:58:46 jah Exp jah $
  8. ;  :History.    09.05.99 started
  9. ;        24.06.99 version 1.0 finished
  10. ;        06.07.99 reworked, wpatch separated
  11. ;  :Requires.    OS V37+
  12. ;  :Copyright.
  13. ;        WDelta is Copyright © 1999 Bert Jahn <wepl@kagi.com>
  14. ;
  15. ;        This program is free software; you can redistribute it and/or
  16. ;        modify it under the terms of the GNU General Public License as
  17. ;        published by the Free Software Foundation; either version 2 of
  18. ;        the License, or (at your option) any later version.
  19. ;
  20. ;        This program is distributed in the hope that it will be
  21. ;        useful, but WITHOUT ANY WARRANTY; without even the implied
  22. ;        warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
  23. ;        PURPOSE. See the GNU General Public License for more details.
  24. ;
  25. ;        You can find the full GNU GPL online at: http://www.gnu.org/
  26. ;
  27. ;  :Language.    68000/68020 Assembler
  28. ;  :Translator.    Barfly V2.9
  29. ;---------------------------------------------------------------------------*
  30. ;##########################################################################
  31.  
  32.     INCDIR    Includes:
  33.     INCLUDE    lvo/exec.i
  34.     INCLUDE    exec/execbase.i
  35.     INCLUDE    exec/memory.i
  36.     INCLUDE    lvo/dos.i
  37.  
  38.     INCLUDE    wdelta.i
  39.     INCLUDE    macros/ntypes.i
  40.  
  41. ;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  42.  
  43. GL    EQUR    A4        ;a4 ptr to Globals
  44. LOC    EQUR    A5        ;a5 for local vars
  45.  
  46. COUNT        ;enables counting on creating wdelta files
  47. ;DEBUG        ;enables some algo checks during creating
  48. ;ASC
  49.  
  50.     STRUCTURE    ReadArgsArray,0
  51.         ULONG    rda_inname
  52.         ULONG    rda_outname
  53.         ULONG    rda_wdname
  54.         ULONG    rda_fc
  55.         ULONG    rda_qc
  56.         LABEL    rda_SIZEOF
  57.  
  58.     NSTRUCTURE    Globals,0
  59.         NAPTR    gl_execbase
  60.         NAPTR    gl_dosbase
  61.         NAPTR    gl_rdargs
  62.         NSTRUCT    gl_rdarray,rda_SIZEOF
  63.         NLONG    gl_insize
  64.         NLONG    gl_inptr
  65.         NLONG    gl_outsize
  66.         NLONG    gl_outptr
  67.         NLONG    gl_wdsize
  68.         NLONG    gl_wdptr
  69.     IFD COUNT
  70.         NLONG    gl_ec
  71.         NLONG    gl_es
  72.         NLONG    gl_cc
  73.         NLONG    gl_cs
  74.         NLONG    gl_ac
  75.         NLONG    gl_as
  76.         NLONG    gl_dc
  77.         NLONG    gl_ds
  78.     ENDC
  79.         NALIGNLONG
  80.         NLABEL    gl_SIZEOF
  81.  
  82. ;##########################################################################
  83.  
  84.     PURE
  85.     SECTION    "",CODE
  86.     OUTPUT    C:WDelta
  87.  
  88. VER    MACRO
  89.         dc.b    "WDelta 1.1 "
  90.     DOSCMD    "WDate >t:date"
  91.     INCBIN    "t:date"
  92.         dc.b    " by Bert Jahn <wepl@kagi.com>"
  93.     ENDM
  94.  
  95.         bra    .start
  96.         dc.b    "$VER: "
  97.         VER
  98.         dc.b    " V37+"
  99.     CNOP 0,2
  100. .start
  101.  
  102. ;##########################################################################
  103.  
  104.         link    GL,#gl_SIZEOF        ;GL = globals
  105.         move.l    (4),(gl_execbase,GL)
  106.  
  107.         move.l    #37,d0
  108.         lea    (_dosname),a1
  109.         move.l    (gl_execbase,GL),a6
  110.         jsr    (_LVOOpenLibrary,a6)
  111.         move.l    d0,(gl_dosbase,GL)
  112.         beq    .nodoslib
  113.  
  114.         lea    (_ver),a0
  115.         bsr    _Print
  116.  
  117.         clr.l    (gl_rdarray+rda_fc,GL)
  118.         clr.l    (gl_rdarray+rda_qc,GL)
  119.  
  120.         lea    (_template),a0
  121.         move.l    a0,d1
  122.         lea    (gl_rdarray,GL),a0
  123.         move.l    a0,d2
  124.         moveq    #0,d3
  125.         move.l    (gl_dosbase,GL),a6
  126.         jsr    (_LVOReadArgs,a6)
  127.         move.l    d0,(gl_rdargs,GL)
  128.         bne    .argsok
  129.         lea    (_readargs),a0
  130.         bsr    _PrintErrorDOS
  131.         bra    .noargs
  132. .argsok
  133.         move.l    #180,d1
  134.         move.l    (gl_rdarray+rda_fc,GL),d0
  135.         beq    .fn
  136.         move.l    d0,a0
  137.         move.l    (a0),d1
  138. .fn        move.l    d1,(gl_rdarray+rda_fc,GL)
  139.  
  140.         move.l    #18,d1
  141.         move.l    (gl_rdarray+rda_qc,GL),d0
  142.         beq    .fc
  143.         move.l    d0,a0
  144.         cmp.l    #1,(a0)
  145.         ble    .fc
  146.         move.l    (a0),d1
  147. .fc        move.l    d1,(gl_rdarray+rda_qc,GL)
  148.  
  149.         bsr    _create
  150.         move.l    d0,d7
  151.  
  152.         move.l    (gl_rdargs,GL),d1
  153.         move.l    (gl_dosbase,GL),a6
  154.         jsr    (_LVOFreeArgs,a6)
  155. .noargs
  156.         move.l    (gl_dosbase,GL),a1
  157.         move.l    (gl_execbase,GL),a6
  158.         jsr    (_LVOCloseLibrary,a6)
  159. .nodoslib
  160.         unlk    GL
  161.         move.l    d7,d0
  162.         rts
  163.  
  164. ;##########################################################################
  165.  
  166. _create        moveq    #20,d7            ;rc
  167.  
  168.         move.l    (gl_execbase,GL),a0
  169.         btst    #AFB_68020,(AttnFlags+1,a0)
  170.         bne    .20ok
  171.         lea    (_lowcpu),a0
  172.         bsr    _Print
  173.         bra    .badcpu
  174. .20ok
  175.         move.l    (gl_rdarray+rda_inname,GL),a0
  176.         bsr    _LoadFileMsg
  177.         move.l    d0,(gl_inptr,GL)
  178.         beq    .noin
  179.         move.l    d1,(gl_insize,GL)
  180.  
  181.         move.l    (gl_rdarray+rda_outname,GL),a0
  182.         bsr    _LoadFileMsg
  183.         move.l    d0,(gl_outptr,GL)
  184.         beq    .noout
  185.         move.l    d1,(gl_outsize,GL)
  186.  
  187.         move.l    (gl_outsize,GL),d0
  188.         add.l    d0,d0
  189.         add.l    #wdlt_wdelta,d0
  190.         move.l    #MEMF_ANY,d1
  191.         move.l    (gl_execbase,GL),a6
  192.         jsr    (_LVOAllocVec,a6)
  193.         move.l    d0,(gl_wdptr,GL)
  194.         bne    .wdok
  195.         lea    _nomem,a0
  196.         bsr    _Print
  197.         bra    .nowd
  198. .wdok
  199.         lea    (_setup),a0
  200.         move.l    (gl_rdarray+rda_qc,GL),-(a7)
  201.         move.l    (gl_rdarray+rda_fc,GL),-(a7)
  202.         move.l    a7,a1
  203.         bsr    _PrintArgs
  204.         add.l    #8,a7
  205.  
  206.         bsr    _create_
  207.  
  208.         move.l    (gl_wdptr,GL),a2
  209.         move.l    #"WDLT",(a2)+
  210.         move.l    a2,a3
  211.         move.l    (gl_insize,GL),(a2)+
  212.         move.l    (gl_outsize,GL),(a2)+
  213.         move.l    (gl_wdsize,GL),(a2)+
  214.         move.l    (gl_insize,GL),d0
  215.         move.l    (gl_inptr,GL),a0
  216.         bsr    _CRC16
  217.         move.w    d0,(a2)+
  218.         move.l    (gl_outsize,GL),d0
  219.         move.l    (gl_outptr,GL),a0
  220.         bsr    _CRC16
  221.         move.w    d0,(a2)+
  222.         move.l    (gl_wdsize,GL),d0
  223.         move.l    (gl_wdptr,GL),a0
  224.         add.l    #wdlt_wdelta,a0
  225.         bsr    _CRC16
  226.         move.w    d0,(a2)+
  227.         move.l    #wdlt_crchd-4,d0
  228.         move.l    a3,a0
  229.         bsr    _CRC16
  230.         move.w    d0,(a2)+
  231.  
  232.         move.l    #wdlt_wdelta,d0
  233.         add.l    (gl_wdsize,GL),d0
  234.         move.l    (gl_wdptr,GL),a0
  235.         move.l    (gl_rdarray+rda_wdname,GL),a1
  236.         bsr    _SaveFileMsg
  237.  
  238.         move.l    #wdlt_wdelta,d0
  239.         add.l    (gl_wdsize,GL),d0
  240.         move.l    d0,-(a7)
  241.         lea    (_outputlen),a0
  242.         move.l    a7,a1
  243.         bsr    _PrintArgs
  244.         addq.l    #4,a7
  245.  
  246.         moveq    #0,d7            ;rc
  247.  
  248.         move.l    (gl_wdptr,GL),a1
  249.         move.l    (gl_execbase,GL),a6
  250.         jsr    (_LVOFreeVec,a6)
  251. .nowd
  252. .freeout
  253.         move.l    (gl_outptr,GL),a1
  254.         move.l    (gl_execbase,GL),a6
  255.         jsr    (_LVOFreeVec,a6)
  256. .noout
  257. .freein
  258.         move.l    (gl_inptr,GL),a1
  259.         move.l    (gl_execbase,GL),a6
  260.         jsr    (_LVOFreeVec,a6)
  261. .noin
  262. .badcpu
  263.         move.l    d7,d0
  264.         rts
  265.  
  266. ; cmd    00 - equ, 5-bit (1..32)
  267. ;    20 - chg, 5-bit (1..32)
  268. ;    40 - add, 5-bit (1..32)
  269. ;    60 - del, 5-bit (1..32)
  270. ;    80 - equ, 13-bit (33..8191+33)
  271. ;    a0 - chg, 13-bit (33..8191+33)
  272. ;    c0 - add, 13-bit (33..8191+33)
  273. ;    e0 - del, 13-bit (33..8191+33)
  274.  
  275. in    EQUR    a0
  276. out    EQUR    a1
  277. wd    EQUR    a2
  278. in2    EQUR    a3
  279. out2    EQUR    LOC
  280. ta    EQUR    a6    ;MUST BE A6!
  281.  
  282. ein    EQUR    d7    ;end input data
  283. eout    EQUR    d1    ;end output data
  284. e4in    EQUR    d2    ;end input data - 4
  285. e4out    EQUR    d3    ;end output data - 4
  286. fn    EQUR    d4    ;find next
  287. q    EQUR    d5    ;quality
  288. t2    EQUR    d6
  289. t1    EQUR    d0    ;MUST BE D0!
  290. t3    EQUR    d3
  291. MAXCNT    = 8191+33
  292. MAXPT    = -1        ;maximal pointer
  293.  
  294. _create_
  295.  
  296.     MC68020
  297.  
  298.     IFD COUNT
  299.         clr.l    (gl_ec,GL)
  300.         clr.l    (gl_es,GL)
  301.         clr.l    (gl_cc,GL)
  302.         clr.l    (gl_cs,GL)
  303.         clr.l    (gl_ac,GL)
  304.         clr.l    (gl_as,GL)
  305.         clr.l    (gl_dc,GL)
  306.         clr.l    (gl_ds,GL)
  307.         moveq    #0,t1
  308.     ENDC
  309.  
  310.     ;initialisation
  311.         sub.w    #16,a7            ;variables for quality
  312.  
  313.         move.l    (gl_inptr,GL),in    ;input start
  314.         move.l    in,ein
  315.         add.l    (gl_insize,GL),ein    ;input end
  316.         move.l    ein,e4in
  317.         subq.l    #4,e4in            ;input end-4
  318.         move.l    (gl_outptr,GL),out    ;output start
  319.         move.l    out,eout
  320.         add.l    (gl_outsize,GL),eout    ;output end
  321.         move.l    eout,e4out
  322.         subq.l    #4,e4out        ;output end-4
  323.         move.l    (gl_wdptr,GL),wd
  324.         add.l    #wdlt_wdelta,wd        ;skip header
  325.  
  326. MINDATALEN = 8
  327.  
  328.     ;check if input or output data is smaller than MINDATALEN bytes
  329.         cmp.l    #MINDATALEN,(gl_insize,GL)
  330.         blo    .tosmall
  331.         cmp.l    #MINDATALEN,(gl_outsize,GL)
  332.         bhs    .lenok
  333.     ;to small, so simple build wdelta by copying output ("add")
  334. .tosmall    move.l    (gl_outsize,GL),t1
  335.         beq    .smallend
  336.     IFD COUNT
  337.         addq.l    #1,(gl_ac,GL)
  338.         add.l    t1,(gl_as,GL)
  339.     ENDC
  340. .ts3        sub.l    #MAXCNT,t1
  341.         bcs    .ts4
  342.         move.w    #$dfff,(wd)+        ;add 8191+33
  343.         move.w    #MAXCNT/4-1,t2
  344. .ts6        move.l    (out)+,(wd)+
  345.         dbf    t2,.ts6
  346.         bra    .ts3
  347. .ts4        add.l    #MAXCNT-1,t1
  348.         bmi    .smallend        ;if equal 8191+33
  349.         move.w    t1,t2
  350.         cmp.w    #32,t1
  351.         bhs    .ts5
  352.         or.b    #$40,t1
  353.         move.b    t1,(wd)+        ;add 1..33
  354.         bra    .ts7
  355. .ts5        sub.w    #32,t1
  356.         or.w    #$c000,t1
  357.         move.w    t1,(wd)+        ;add 33..8191+33
  358. .ts7        move.b    (out)+,(wd)+
  359.         dbf    t2,.ts7
  360.         bra    .smallend
  361.  
  362. .finish_eq_opt
  363.     IFD DEBUG
  364.         beq    .finish_eq
  365.         illegal
  366.     ENDC
  367.         bra    .finish_eq        ;this is for optimizing
  368.  
  369.     ;we have a valid input and output now
  370.     ;depending on the equality of the first word we enter the search
  371.     ;routine for equal or for sync
  372. .lenok        move.w    (in),t1
  373.         cmp.w    (out),t1
  374.         bne    .searchsync
  375.     QUAD
  376. .ncnteq        move.l    out,t1
  377. .cnteq        cmp.l    eout,out
  378.         bhs    .finish_eq_opt
  379.         cmp.l    ein,in
  380.         bhs    .finish_eq_opt
  381.         cmp.b    (in)+,(out)+
  382.         beq    .cnteq
  383.  
  384.         subq.l    #1,in            ;correct post-increment
  385.         subq.l    #1,out            ;correct post-increment
  386.  
  387. WRITE_EQU MACRO
  388.     IFD DEBUG
  389.         ;check if wdelta is larger than output size
  390.         move.l    (gl_outsize,GL),t2
  391.         add.l    (gl_wdptr,GL),t2
  392.         cmp.l    t2,wd
  393.         blo    .i\@
  394.         illegal
  395. .i\@
  396.     ENDC
  397.         move.l    out,t2
  398.         sub.l    t1,t2            ;t2 = amount of equal bytes
  399.     IFD DEBUG
  400.         bgt    .5\@            ;cannot be zero/negative
  401.         illegal
  402. .5\@
  403.     ENDC
  404.     IFD COUNT
  405.         addq.l    #1,(gl_ec,GL)
  406.         add.l    t2,(gl_es,GL)
  407.     ENDC
  408.     IFD ASC
  409.         movem.l    d0-d2/a0-a2/a6,-(a7)
  410.         move.l    t2,-(a7)
  411.         pea    (_equ)
  412.         move.l    in,d0
  413.         sub.l    (gl_inptr,GL),d0
  414.         sub.l    t2,d0
  415.         move.l    d0,-(a7)
  416.         move.l    out,d0
  417.         sub.l    (gl_outptr,GL),d0
  418.         sub.l    t2,d0
  419.         move.l    d0,-(a7)
  420.         move.l    a7,d2
  421.         move.l    (gl_dosbase,GL),a6
  422.         lea    (_asc1),a0
  423.         move.l    a0,d1
  424.         jsr    (_LVOVPrintf,a6)
  425.         add.w    #16,a7
  426.         movem.l    (a7)+,_MOVEMREGS
  427.     ENDC
  428. .4\@        sub.l    #MAXCNT,t2
  429.         bcs    .3\@
  430.         move.w    #$9fff,(wd)+        ;equ 8191+33
  431.         bra    .4\@
  432. .3\@        add.l    #MAXCNT-1,t2
  433.         bmi    .2\@            ;is negative if t2 was a multiple of MAXCNT
  434.         cmp.w    #32,t2
  435.         bhs    .1\@
  436.         move.b    t2,(wd)+        ;equ 1..33
  437.         bra    .2\@
  438. .1\@        sub.w    #32,t2
  439.         or.w    #$8000,t2
  440.         move.w    t2,(wd)+        ;equ 33..8191+33
  441. .2\@
  442.     ENDM
  443.  
  444.         WRITE_EQU
  445.  
  446.     ;search for new sync
  447. .searchsync    move.l    in,in2
  448.         move.l    out,out2
  449.         move.l    #MAXPT,fn        ;(unsigned)
  450.         move.l    #$80000000,(a7)        ;(signed) lowest possible quality
  451.         bra    .ss1_in
  452.  
  453.     ;---------------------------------------
  454.     ;search "eq", "add", "del"
  455.     QUAD
  456. .ss1        move.l    (in2),t1        ;t1 = contens of in2
  457.         move.l    (out2),t2        ;t2 = contens of out2
  458.         cmp.l    t1,t2
  459.         beq    .ss1_fchg
  460.  
  461.         move.l    in,ta            ;ta = temp in ptr
  462. .ss1_add    cmp.l    (ta),t2
  463.         beq    .ss1_fadd
  464. .ss1_addr    addq.l    #1,ta
  465.         cmp.l    ta,in2
  466.         bhi    .ss1_add
  467.  
  468.         move.l    out,ta            ;ta = temp out ptr
  469. .ss1_del    cmp.l    (ta),t1
  470.         beq    .ss1_fdel
  471. .ss1_delr    addq.l    #1,ta
  472.         cmp.l    ta,out2
  473.         bhi    .ss1_del
  474.  
  475. .ss1_in        cmp.l    e4in,in2        ;end input ?
  476.         bhs    .ss_endin
  477.         addq.l    #1,in2
  478.         cmp.l    e4out,out2        ;end output ?
  479.         bhs    .ss_endout
  480.         addq.l    #1,out2
  481.     ;check if end of fn is reached
  482.         cmp.l    fn,out2
  483.         blo    .ss1
  484.     ;perform best found command
  485.         jmp    ([12,a7])
  486.     ;    nop                ;because a bug in bdebug!
  487.  
  488. RANKINITC MACRO
  489.     ;add half amount of addable qual
  490.         move.l    (rda_qc+gl_rdarray,GL),q
  491.         mulu    q,q
  492.         lsr.l    #2,q
  493.         add.l    in,q
  494.     ;    move.l    in,q
  495.         sub.l    in2,q            ;search offset
  496.         asr.l    #1,q
  497.     ENDM
  498. RANKINIT MACRO
  499.     ;q  = distance from in/out
  500.         asr.l    #1,q
  501.     ENDM
  502. RANKDO MACRO
  503.         add.l    t3,q
  504.     ;    addq.l    #1,q
  505.     ENDM
  506. RANKPOST MACRO
  507.         subq.l    #1,t3
  508.     ENDM
  509.  
  510. .ss1_fchg
  511.     ;save regs
  512.         movem.l    t2/t3/in2/out2,-(a7)
  513.     ;calculate quality
  514.         RANKINITC
  515.         move.l    (rda_qc+gl_rdarray,GL),t3
  516.         move.l    t3,t2
  517.         add.l    out2,t2
  518.         cmp.l    eout,t2
  519.         bls    .fchg2
  520.         move.l    eout,t2
  521. .fchg2        cmp.b    (in2)+,(out2)+
  522.         bne    .fchg1
  523.         RANKDO
  524. .fchg1        RANKPOST
  525.         cmp.l    in2,ein
  526.         bls    .fchg3
  527.         cmp.l    out2,t2
  528.         bhi    .fchg2
  529. .fchg3    ;restore regs
  530.         movem.l    (a7)+,_MOVEMREGS
  531.     ;checks if fn is already set
  532.         tst.l    fn
  533.         bmi    .fchg4
  534.     ;check against existing quality
  535.         cmp.l    (a7),q
  536.         ble    .chgr
  537.     ;save setup
  538. .fchg5        movem.l    q/out2,(a7)
  539.         move.l    #.chg,(12,a7)
  540.         bra    .chgr
  541.     ;set fn
  542. .fchg4        move.l    (rda_fc+gl_rdarray,GL),fn
  543.         add.l    out,fn
  544.         bra    .fchg5
  545.  
  546. RANKADD    MACRO
  547.     ;save regs
  548.         movem.l    t2/t3/ta/out2,-(a7)
  549.     ;calculate quality
  550.         move.l    out,q
  551.         sub.l    out2,q
  552.         add.l    in,q
  553.         sub.l    ta,q
  554.         RANKINIT
  555.         move.l    (rda_qc+gl_rdarray,GL),t3
  556.         move.l    t3,t2
  557.         add.l    out2,t2
  558.         cmp.l    eout,t2
  559.         bls    .2\@
  560.         move.l    eout,t2
  561. .2\@        cmp.b    (ta)+,(out2)+
  562.         bne    .1\@
  563.         RANKDO
  564. .1\@        RANKPOST
  565.         cmp.l    ta,ein
  566.         bls    .3\@
  567.         cmp.l    out2,t2
  568.         bhi    .2\@
  569. .3\@    ;restore regs
  570.         movem.l    (a7)+,_MOVEMREGS
  571.     ;checks if fn is already set
  572.         tst.l    fn
  573.         bmi    .4\@
  574.     ;check against existing quality
  575.         cmp.l    (a7),q
  576.         ble    \1
  577.     ;save setup
  578. .5\@        movem.l    q/ta/out2,(a7)
  579.         move.l    #.add,(12,a7)
  580.         bra    \1
  581.     ;set fn
  582. .4\@        move.l    (rda_fc+gl_rdarray,GL),fn
  583.         add.l    out,fn
  584.         bra    .5\@
  585.     ENDM
  586.  
  587. .ss1_fadd    RANKADD    .ss1_addr
  588.  
  589. RANKDEL    MACRO
  590.     ;save regs
  591.         movem.l    t2/t3/ta/in2,-(a7)
  592.     ;calculate quality
  593.         move.l    out,q
  594.         sub.l    ta,q
  595.         add.l    in,q
  596.         sub.l    in2,q
  597.         RANKINIT
  598.         move.l    (rda_qc+gl_rdarray,GL),t3
  599.         move.l    t3,t2
  600.         add.l    in2,t2
  601.         cmp.l    ein,t2
  602.         bls    .2\@
  603.         move.l    ein,t2
  604. .2\@        cmp.b    (ta)+,(in2)+
  605.         bne    .1\@
  606.         RANKDO
  607. .1\@        RANKPOST
  608.         cmp.l    ta,eout
  609.         bls    .3\@
  610.         cmp.l    in2,t2
  611.         bhi    .2\@
  612. .3\@    ;restore regs
  613.         movem.l    (a7)+,_MOVEMREGS
  614.     ;checks if fn is already set
  615.         tst.l    fn
  616.         bmi    .4\@
  617.     ;check against existing quality
  618.         cmp.l    (a7),q
  619.         ble    \1
  620.     ;save setup
  621. .5\@        movem.l    q/ta/in2,(a7)
  622.         move.l    #.del,(12,a7)
  623.         bra    \1
  624.     ;set fn
  625. .4\@        move.l    (rda_fc+gl_rdarray,GL),fn
  626.         add.l    out,fn
  627.         bra    .5\@
  628.     ENDM
  629.  
  630. .ss1_fdel    RANKDEL    .ss1_delr
  631.  
  632.     ;---------------------------------------
  633.     ;search "add", "del" ("eq" already found)
  634.     QUAD
  635. .ss2        move.l    (in2),t1        ;t1 = contens of in2
  636.         move.l    (out2),t2        ;t2 = contens of out2
  637. .chgr
  638.         move.l    in,ta            ;ta = temp in ptr
  639. .ss2_add    cmp.l    (ta),t2
  640.         beq    .ss2_fadd
  641. .ss2_addr    addq.l    #1,ta
  642.         cmp.l    ta,in2
  643.         bhi    .ss2_add
  644.  
  645.         move.l    out,ta            ;ta = temp out ptr
  646. .ss2_del    cmp.l    (ta),t1
  647.         beq    .ss2_fdel
  648. .ss2_delr    addq.l    #1,ta
  649.         cmp.l    ta,out2
  650.         bhi    .ss2_del
  651.  
  652.         cmp.l    e4in,in2        ;end input ?
  653.         bhs    .ss_endin
  654.         addq.l    #1,in2
  655.         cmp.l    e4out,out2        ;end output ?
  656.         bhs    .ss_endout
  657.         addq.l    #1,out2
  658.     ;check if end of fn is reached
  659.         cmp.l    fn,out2
  660.         blo    .ss2
  661.     ;perform best found command
  662.         jmp    ([12,a7])
  663.     ;    nop                ;because a bug in bdebug!
  664.  
  665. .ss2_fadd    RANKADD    .ss2_addr
  666. .ss2_fdel    RANKDEL    .ss2_delr
  667.  
  668.     ;---------------------------------------
  669.     ;searches "add", "del" because end of input reached
  670. .ss_endin
  671.     ;check if at least 4 bytes are available on out2
  672.         bne    .finish
  673.     ;set t1
  674.         move.l    (in2),t1
  675.         bra    .ss_ei_in
  676.  
  677. .ss_ei        move.l    (out2),t2        ;t2 = contens of out2
  678.         move.l    in,ta            ;ta = temp in ptr
  679. .ss_ei_add    cmp.l    (ta),t2
  680.         beq    .ss_ei_fadd
  681. .ss_ei_addr    addq.l    #1,ta
  682.         cmp.l    ta,in2
  683.         bhi    .ss_ei_add
  684.  
  685.         move.l    out,ta            ;ta = temp out ptr
  686. .ss_ei_del    cmp.l    (ta),t1
  687.         beq    .ss_ei_fdel
  688. .ss_ei_delr    addq.l    #1,ta
  689.         cmp.l    ta,out2
  690.         bhi    .ss_ei_del
  691.  
  692. .ss_ei_in    cmp.l    e4out,out2        ;end output ?
  693.         bhs    .ss_ei_eo
  694.         addq.l    #1,out2
  695.     ;check if end of fn is reached
  696.         cmp.l    fn,out2
  697.         blo    .ss_ei
  698.     ;perform best found command
  699. .ss_ei_p    jmp    ([12,a7])
  700.     ;    nop                ;because a bug in bdebug!
  701. .ss_ei_eo    tst.l    fn
  702.         bpl    .ss_ei_p
  703.         bra    .finish
  704.  
  705. .ss_ei_fadd    RANKADD    .ss_ei_addr
  706. .ss_ei_fdel    RANKDEL    .ss_ei_delr
  707.  
  708.     ;---------------------------------------
  709.     ;searches "add", "del" because end of output reached
  710. .ss_endout
  711.     ;check if at least 4 bytes are available on out2
  712.         bne    .finish
  713.     ;set t2
  714.         move.l    (out2),t2
  715.     ;if fn is already set, remap it to "in address"
  716.         tst.l    fn
  717.         bmi    .ss_eo
  718.         sub.l    out,fn            ;bytes to check left
  719.         add.l    in,fn
  720.  
  721. .ss_eo        move.l    in,ta            ;ta = temp in ptr
  722. .ss_eo_add    cmp.l    (ta),t2
  723.         beq    .ss_eo_fadd
  724. .ss_eo_addr    addq.l    #1,ta
  725.         cmp.l    ta,in2
  726.         bhi    .ss_eo_add
  727.  
  728.         move.l    (in2),t1        ;t1 = contens of in2
  729.         move.l    out,ta            ;ta = temp out ptr
  730. .ss_eo_del    cmp.l    (ta),t1
  731.         beq    .ss_eo_fdel
  732. .ss_eo_delr    addq.l    #1,ta
  733.         cmp.l    ta,out2
  734.         bhi    .ss_eo_del
  735.  
  736.         cmp.l    e4in,in2        ;end input ?
  737.         bhs    .ss_eo_ei
  738.         addq.l    #1,in2
  739.     ;check if end of fn is reached
  740.         cmp.l    fn,in2
  741.         blo    .ss_eo
  742.     ;perform best found command
  743. .ss_eo_p    jmp    ([12,a7])
  744.     ;    nop                ;because a bug in bdebug!
  745. .ss_eo_ei    tst.l    fn
  746.         bpl    .ss_eo_p
  747.         bra    .finish
  748.  
  749. .ss_eo_fadd    RANKADD    .ss_eo_addr
  750. .ss_eo_fdel    RANKDEL    .ss_eo_delr
  751.  
  752.     ;---------------------------------------
  753.     ;perform "chg"
  754.     ;(4,a7) = out2
  755. .chg        move.l    (4,a7),t1
  756.         sub.l    out,t1
  757.         bsr    .do_chg
  758.         bra    .ncnteq
  759.  
  760.     ;---------------------------------------
  761.     ;really do "chg"
  762.     ;t1 = amount of bytes to change
  763.     ;in,out will be changed appropriate
  764. .do_chg        add.l    t1,in            ;skip input
  765.     IFD COUNT
  766.         addq.l    #1,(gl_cc,GL)
  767.         add.l    t1,(gl_cs,GL)
  768.     ENDC
  769.     IFD ASC
  770.         movem.l    d0-d2/a0-a2/a6,-(a7)
  771.         move.l    t1,-(a7)
  772.         pea    (_chg)
  773.         move.l    in,d0
  774.         sub.l    (gl_inptr,GL),d0
  775.         move.l    d0,-(a7)
  776.         move.l    out,d0
  777.         sub.l    (gl_outptr,GL),d0
  778.         move.l    d0,-(a7)
  779.         move.l    a7,d2
  780.         move.l    (gl_dosbase,GL),a6
  781.         lea    (_asc1),a0
  782.         move.l    a0,d1
  783.         jsr    (_LVOVPrintf,a6)
  784.         add.w    #16,a7
  785.         movem.l    (a7)+,_MOVEMREGS
  786.     ENDC
  787. .chg3        sub.l    #MAXCNT,t1
  788.         bcs    .chg4
  789.         move.w    #$bfff,(wd)+        ;chg 8191+33
  790.         move.w    #MAXCNT/4-1,t2
  791. .chg6        move.l    (out)+,(wd)+
  792.         dbf    t2,.chg6
  793.         bra    .chg3
  794. .chg4        add.l    #MAXCNT-1,t1
  795.         bmi    .ncnteq            ;is negative if t1 was a multiple of MAXCNT
  796.         move.w    t1,t2
  797.         cmp.w    #32,t1
  798.         bhs    .chg5
  799.         or.b    #$20,t1
  800.         move.b    t1,(wd)+        ;chg 1..33
  801.         bra    .chg7
  802. .chg5        sub.w    #32,t1
  803.         or.w    #$a000,t1
  804.         move.w    t1,(wd)+        ;chg 33..8191+33
  805. .chg7        move.b    (out)+,(wd)+
  806.         dbf    t2,.chg7
  807.         rts
  808.  
  809.     ;---------------------------------------
  810.     ;perform "del"
  811.     ;either only "del" or "chg"+"del" (which can replaced by "del"+"add")
  812.     ;(4,a7) = in2 = offset in input stream
  813.     ;(8,a7) = ta = offset in output stream
  814. .del        move.l    (8,a7),t1
  815.         sub.l    out,t1
  816.         beq    .del1
  817.         bsr    .do_chg
  818. .del1        move.l    (4,a7),t1
  819.         sub.l    in,t1
  820.     IFD DEBUG
  821.         cmp.l #10000,t1
  822.         blo .i1
  823.         illegal
  824. .i1
  825.     ENDC
  826.     ;perform del command
  827.     IFD COUNT
  828.         addq.l    #1,(gl_dc,GL)
  829.         add.l    t1,(gl_ds,GL)
  830.     ENDC
  831.     IFD ASC
  832.         movem.l    d0-d2/a0-a2/a6,-(a7)
  833.         move.l    t1,-(a7)
  834.         move.l    out2,t1
  835.         sub.l    out,t1
  836.         move.l    t1,-(a7)
  837.         move.l    in,d0
  838.         sub.l    (gl_inptr,GL),d0
  839.         move.l    d0,-(a7)
  840.         move.l    out,d0
  841.         sub.l    (gl_outptr,GL),d0
  842.         move.l    d0,-(a7)
  843.         move.l    a7,d2
  844.         move.l    (gl_dosbase,GL),a6
  845.         lea    (_asc2),a0
  846.         move.l    a0,d1
  847.         jsr    (_LVOVPrintf,a6)
  848.         add.w    #16,a7
  849.         movem.l    (a7)+,_MOVEMREGS
  850.     ENDC
  851.         add.l    t1,in            ;skip input stream
  852. .del3        sub.l    #MAXCNT,t1
  853.         bcs    .del4
  854.         move.w    #$ffff,(wd)+        ;del 8191+33
  855.         bra    .del3
  856. .del4        add.l    #MAXCNT-1,t1
  857.         bmi    .ncnteq
  858.         cmp.w    #32,t1
  859.         bhs    .del5
  860.         or.b    #$60,t1
  861.         move.b    t1,(wd)+        ;del 1..33
  862.         bra    .ncnteq
  863. .del5        sub.w    #32,t1
  864.         or.w    #$e000,t1
  865.         move.w    t1,(wd)+        ;del 33..8191+33
  866.         bra    .ncnteq
  867.  
  868.     ;---------------------------------------
  869.     ;perform "add"
  870.     ;either only "add" or "chg"+"add" (which can replaced by "del"+"add")
  871.     ;(4,a7) = out2 = offset in output stream
  872.     ;(8,a7) = ta = offset in input stream
  873.     ;amount "del" = ta - in
  874.     ;amount "add" = out2 - out
  875. .add        move.l    (8,a7),t1
  876.         sub.l    in,t1
  877.         beq    .add1
  878.         bsr    .do_chg
  879. .add1        move.l    (4,a7),t1
  880.         sub.l    out,t1
  881.     IFD DEBUG
  882.         cmp.l #10000,t1
  883.         blo .i2
  884.         illegal
  885. .i2
  886.     ENDC
  887.     ;perform add command
  888.     IFD COUNT
  889.         addq.l    #1,(gl_ac,GL)
  890.         add.l    t1,(gl_as,GL)
  891.     ENDC
  892. .add3        sub.l    #MAXCNT,t1
  893.         bcs    .add4
  894.         move.w    #$dfff,(wd)+        ;add 8191+33
  895.         move.w    #MAXCNT/4-1,t2
  896. .add6        move.l    (out)+,(wd)+
  897.         dbf    t2,.add6
  898.         bra    .add3
  899. .add4        add.l    #MAXCNT-1,t1
  900.         bmi    .chg
  901.         move.w    t1,t2
  902.         cmp.w    #32,t1
  903.         bhs    .add5
  904.         or.b    #$40,t1
  905.         move.b    t1,(wd)+        ;add 1..33
  906.         bra    .add7
  907. .add5        sub.w    #32,t1
  908.         or.w    #$c000,t1
  909.         move.w    t1,(wd)+        ;add 33..8191+33
  910. .add7        move.b    (out)+,(wd)+
  911.         dbf    t2,.add7
  912.         bra    .ncnteq
  913.  
  914.     ;end of calculation, because
  915.     ; - end input stream during eq search
  916.     ; - end output stream during eq search
  917. .finish_eq    WRITE_EQU
  918.  
  919.     ;end of calculation, because
  920.     ; - end input stream during sync search
  921.     ; - end output stream during sync search
  922. .finish
  923.     IFD COUNT
  924.         move.l    ein,t1
  925.         sub.l    in,t1
  926.         beq    .finish1
  927.         addq.l    #1,(gl_dc,GL)
  928.         add.l    t1,(gl_ds,GL)
  929. .finish1
  930.     ENDC
  931.         move.l    eout,t1
  932.         sub.l    out,t1
  933.         beq    .finish_end
  934.     IFD COUNT
  935.         addq.l    #1,(gl_ac,GL)
  936.         add.l    t1,(gl_as,GL)
  937.     ENDC
  938.  
  939. .endin3        sub.l    #MAXCNT,t1
  940.         bcs    .endin4
  941.         move.w    #$dfff,(wd)+        ;add 8191+33
  942.         move.w    #MAXCNT/4-1,t2
  943. .endin6        move.l    (out)+,(wd)+
  944.         dbf    t2,.endin6
  945.         bra    .endin3
  946. .endin4        add.l    #MAXCNT-1,t1
  947.         bmi    .finish_end
  948.         move.w    t1,t2
  949.         cmp.w    #32,t1
  950.         bhs    .endin5
  951.         or.b    #$40,t1
  952.         move.b    t1,(wd)+        ;add 1..33
  953.         bra    .endin7
  954. .endin5        sub.w    #32,t1
  955.         or.w    #$c000,t1
  956.         move.w    t1,(wd)+        ;add 33..8191+33
  957. .endin7        move.b    (out)+,(wd)+
  958.         dbf    t2,.endin7
  959.  
  960. .finish_end
  961. .smallend
  962.         add.w    #16,a7
  963.  
  964.         sub.l    (gl_wdptr,GL),wd
  965.         sub.l    #wdlt_wdelta,wd
  966.         move.l    wd,(gl_wdsize,GL)
  967.  
  968.     IFD COUNT
  969.         lea    (_debug),a0
  970.         move.l    (gl_ds,GL),-(a7)
  971.         move.l    (gl_dc,GL),-(a7)
  972.         move.l    (gl_as,GL),-(a7)
  973.         move.l    (gl_ac,GL),-(a7)
  974.         move.l    (gl_cs,GL),-(a7)
  975.         move.l    (gl_cc,GL),-(a7)
  976.         move.l    (gl_es,GL),-(a7)
  977.         move.l    (gl_ec,GL),-(a7)
  978.         move.l    a7,a1
  979.         bsr    _PrintArgs
  980.         add.l    #8*4,a7
  981.     ENDC
  982.  
  983.     MC68000
  984.  
  985.         rts
  986.  
  987. ;##########################################################################
  988.  
  989.     INCLUDE    crc16.s
  990.  
  991.     INCDIR    Sources:
  992.     INCLUDE    dosio.i
  993.     ;    CheckBreak
  994.         Print
  995.         PrintLn
  996.     INCLUDE    error.i
  997.         PrintErrorDOS
  998.     INCLUDE    files.i
  999.         LoadFileMsg
  1000.         SaveFileMsg
  1001.  
  1002. ;##########################################################################
  1003.  
  1004.     IFD COUNT
  1005. _debug        dc.b    "equal%8ld chunks%7ld bytes",10
  1006.         dc.b    "changed%6ld chunks%7ld bytes",10
  1007.         dc.b    "added%8ld chunks%7ld bytes",10
  1008.         dc.b    "deleted%6ld chunks%7ld bytes",10,0
  1009.     ENDC
  1010.     IFD ASC
  1011. _asc1        dc.b    "in=%6lx out=%6lx  %s %3lx bytes",10,0
  1012. _equ        dc.b    "equ",0
  1013. _chg        dc.b    "chg",0
  1014. _asc2        dc.b    "in=%6lx out=%6lx  del %3lx bytes add %3lx bytes",10,0
  1015.     ENDC
  1016. _outputlen    dc.b    "output length is %ld bytes",10,0
  1017. _setup        dc.b    "forward check %ld bytes, quality compare %ld bytes",10,0
  1018. _lowcpu        dc.b    "sorry, creating wdelta files requires a MC68020 or better",10,0
  1019. _nomem        dc.b    "not enough free memory",10,0
  1020. _readargs    dc.b    "read arguments",0
  1021. _dosname    dc.b    "dos.library",0
  1022. _template    dc.b    "InFile/A"        ;file to apply patch
  1023.         dc.b    ",OutFile/A"        ;resulting file
  1024.         dc.b    ",WDeltaFile/A"        ;wdelta file
  1025.         dc.b    ",FC/K/N"
  1026.         dc.b    ",QC/K/N"
  1027.         dc.b    0
  1028.  
  1029. _ver        VER
  1030.         dc.b    10,0
  1031.  
  1032. ;##########################################################################
  1033.  
  1034.     END
  1035.